package com.putable.cgw.protocol;

/**
 * A 'constants-only' interface defining the elements and structure of the CGW
 * protocol, with this Javadoc serving as the primary 'Packet dictionary'
 * document. Each byte field documented here (with the exception of
 * {@link #UNINIT}) represents a 'type code' for a particular kind of CGW
 * {@link Packet} that can occur during a CGW protocol exchange between a client
 * and a server.
 * <p>
 * A CGW protocol exchange can be viewed as having four basic 'phases', not all
 * of which necessarily occur in any given exchange:
 * <ol>
 * 
 * <li><b>Initiation phase:</b> The server listens for connections. A client
 * connects to the server. The server sends a {@link #SERVER} packet. The client
 * responds with a {@link #CLIENT} packet.
 * <p>
 * If all is well, the server 'authorizes' the client and sends {@link #AUTH} to
 * the client, and then this protocol exchange moves into the 'active' phase. If
 * a problem occurs (such as an incorrect password), the protocol moves instead
 * into the 'error' phase.</li>
 * 
 * <li><b>Active phase:</b> When a new client enters the active phase, the
 * server broadcasts a {@link #JOIN} to all authorized clients (including the
 * new client) announcing the new arrival. In addition, following the
 * <code>JOIN</code> the server also sends just to the newly-arrived client
 * enough additional packets that that client can render the current situation.
 * <p>
 * Such a 'personalized startup package' of packets delivered just to a new
 * client includes {@link #JOIN} packets identifying the other active players, a
 * {@link #RESET} to flush any prior gang and button information in the client,
 * and then {@link #GANG} packets as needed to define the current state of all
 * the gangs, and likewise any needed {@link #BUTTON} packets defining what soft
 * buttons are currently available. The contents of the 'startup package' MUST
 * be such that at the conclusion of processing those packets, the newly-arrived
 * client will possess all the appropriate gang and button state as the other
 * players, so that the henceforth the new client will receive just the same
 * {@link #UPDATE} packets as suffices for the other preexisting players, and
 * will be able to {@link #CLICK} on buttons appropriately if desired.
 * <p>
 * (As the generation and delivery of such a 'startup package' may put a
 * considerable load on a server if there is complex activity, a server MAY
 * delay for a period of time between the delivery of the {@link #AUTH} and the
 * subsequent {@link #JOIN}.
 * <p>
 * In general, during the active phase many different types of packets may be
 * exchanged depending on what is occurring and on implementation-dependent
 * characteristics of the particular server. One important general point to
 * note, is that it <i>is</i> allowable for a server to have multiple different
 * 'active sets' of client protocol exchanges active at the same time.
 * <p>
 * For example, if a server was handling several clients each playing separate
 * instances of single-player games, a development team may choose to 'isolate'
 * those clients from each other -- so that essentially they would be unaware of
 * each other's existence. Or they might be 'nearly-isolated', for example with
 * a status message indicating the total number of players on the server, but no
 * other information provided. All these matters are implementation-dependent.
 * <p>
 * However, this possible 'segregation of actives' impacts the interpretation of
 * the packet dictionary documentation below. For example, {@link #CHAT} with an
 * empty <code>to</code> argument is documented being broadcast to 'all active
 * players' -- but that must be interpreted relative to the server's
 * implementation-specific design decisions about player interactivity. Clients
 * in single-player games MAY apparently have no one to chat with (but
 * themselves).
 * <p>
 * It emphatically <b><i>is</i></b> allowed for a server to limit a client's
 * awareness of other client's as the server deems appropriate, but in any case
 * the server SHOULD do this for reasons that plausibly enhance playability and
 * the game experience overall.
 * <p>
 * <u>Throughout this document, when reference is made to 'all active players',
 * that is to be interpreted as 'all appropriate active players' as necessary in
 * light of this allowable segregation of actives.</u>
 * <p>
 * The active phase of a CGW protocol instance ends when the server broadcasts a
 * {@link #LEAVE} packet referring to the client of this particular CGW
 * instance.
 * <p>
 * A {@link #LEAVE} packet MUST be broadcast to all active players whenever a
 * client protocol exchange leaves the active phase via any means whatsoever,
 * including the occurence of an error. Failure to do so is a server protocol
 * violation.
 * <p>
 * Note in light of the above discussion of 'segregation of actives', even if a
 * player merely changes the 'active set' they are associated with, that must be
 * accounted for by the server as a {@link #LEAVE} from the old 'active set' and
 * and {@link #JOIN} to the new one.
 * </p>
 * <p>
 * The LEAVE packet tells all still authorized clients that this client is no
 * longer authorized, and its player id is no longer associated with that
 * client. Since this particular client is no longer authorized at the time the
 * {@link #LEAVE} is sent, a client will never receive a LEAVE packet specifying
 * itself.
 * <p>
 * A client is 'deactivated', and a {@link #LEAVE} is broadcast identifying that
 * client, in two (or maybe three) possible ways:
 * <ol>
 * <li> Some kind of protocol error is detected, in which case the 'error' phase
 * is entered, or</li>
 * <li>when the server sends a {@link #DIED} packet to the client, in which
 * case the 'close' phase is entered, and</li>
 * <li>possibly when the server changes the 'active set' the client is in, in
 * which case the 'active' phase of the protocol exchange actually persists, and
 * that client receives another {@link #JOIN} message announcing its
 * (re-)arrival into a new active set.</li>
 * </ol>
 * <p>
 * If a client wishes to initiate the process of leaving the active phase, it
 * sends a {@link #QUIT} packet to the server), which is one thing that will
 * provoke a {@link #DIED} reponse from the server and a transition to the
 * 'close' phase. </li>
 * 
 * <li><b>Error phase:</b> The error phase is entered when an unexpected
 * condition arises during a protocol exchange, which can occur for a wide range
 * of reasons:
 * <ul>
 * <li>A bug in the server-side CGW protocol implementation caused it to send a
 * packet containing a protocol violation, or a correct packet but at an
 * incorrect time, etc.</li>
 * <li>A bug in the client-side CGW protocol implementation caused it to send a
 * packet containing a protocol violation, or a correct packet but at an
 * incorrect time, etc.</li>
 * <li>A bug in the CGW protocol specification -- an ambiguity or internal
 * contradiction -- that led to incompatible client and server protocol
 * implementations, causing a packet more or less legitimately believed to be
 * correct by the sender's implementor to be more or less legitimately believed
 * to be incorrect by the receiver's implementor.</li>
 * <li>A hardware problem -- in client, server, or network -- leading to a
 * broken TCP connection.</li>
 * <li>Insufficient computational power or communications bandwidth -- in
 * client, server, or network -- leading to an unreasonably large buffer of
 * outbound data awaiting transmission.</li>
 * <li>Malicious attempts to probe for vulnerabilities or otherwise abuse a CGW
 * server or client.</li>
 * </ul>
 * <p>
 * When an {@link #ERROR} packet is received by either client or server, the
 * protocol exchange is deemed 'unsuccessfully concluded', and the TCP
 * connection is completely closed (i.e., the input side is closed, and the
 * output side is closed if it was still open), and any clean-up necessary is
 * performed.</li>
 * 
 * <li><b>Close phase:</b> The close phase of a CGW protocol exchange is
 * entered when a client has exited the active phase via 'dying' -- whether that
 * occurs due to an 'actual' in-game 'death event', or due to the client
 * initiating the death by issuing a {@link #QUIT} packet.
 * <p>
 * During the close phase, both client and server perform the following sequence
 * of steps:
 * <ol>
 * <li>They send a {@link #GOODBYE} packet to the other party, including some
 * final message text, then</li>
 * <li>They close the <i>output side</i> of their TCP connection only, while
 * continuing to wait for data on the <i>input side</i> that TCP connection.
 * </li>
 * <li>If more than 30 seconds pass without receiving the corresponding
 * {@link #GOODBYE} Packet (or an {@link #ERROR} packet), then the input side of
 * the connection is closed in any case, the protocol exchange is deemed
 * 'unsuccessfully concluded', and any other clean-up necessary is then
 * performed.</li>
 * <li>If, on the other hand, the final {@link #GOODBYE} packet <i>is</i> read
 * on the still-open inbound side of the TCP connection within a reasonable
 * amount of time, then the <i>input side</i> of the connection is also closed,
 * the protocol exchange is deemed 'successfully concluded', and any other
 * clean-up necessary is then performed.</li>
 * </ol>
 * </ul>
 * <p>
 * A substantial mark of quality for any CGW protocol implementation -- client
 * or server -- is that it can reliably and mutually achieve protocol exchange
 * 'successfully concluded' with any other conforming CGW protocol
 * implementation (of the complementary type, of course) -- even if that
 * implementation was produced by an entirely different development team -- so
 * long as there are no hardware or network errors or excessive delays.
 * </p>
 * </ol>
 * 
 * @author ackley
 * @version 1b
 */
public interface CGW {
    /**
     * The CGW protocol version defined by this interface. CGW servers are
     * encouraged to use this constant in generating their initial
     * {@link #SERVER} packet arguments, and CGW clients are encouraged to
     * likewise check that received value against this constant for determining
     * compatibility.
     */
    static final int VERSION = 1;

    /**
     * Special 'uninitialized value' code, never used in transmitted packets.
     * <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>neither direction</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>None</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>0</td>
     * </tr>
     * </table> Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * </table>
     * <p>
     */
    static final byte UNINIT = 0; // x; no; none

    /**
     * First message sent by server. <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>server to single client</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Initialization</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>3</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>version</code></i></td>
     * <td>Integer.valueOf(String)</td>
     * <td>The CGW version protocol in use (currently must be "1")</td>
     * </tr>
     * <tr>
     * <td><code>group</code></i></td>
     * <td>Non-empty String</td>
     * <td>The name of the group that produced this server</td>
     * </tr>
     * <tr>
     * <td><code>challenge</code></i></td>
     * <td>Non-empty String</td>
     * <td>A challenge string for authentication that is very unlikely to be
     * used more than once</td>
     * </tr>
     * </table>
     */
    static final byte SERVER = UNINIT + 1; // s->c; no; version=int,

    // group=string,

    // challenge=string

    /**
     * First message sent by client. Sent <i>after</i> receiving the
     * <code>SERVER</code> packet <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>client to server only</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Initialization</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>3</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>group</code></i></td>
     * <td>Non-empty String</td>
     * <td>The name of the group that produced this client</td>
     * </tr>
     * <tr>
     * <td><code>user</code></i></td>
     * <td>Non-empty String</td>
     * <td>The name of the user that is running this client (and used in
     * authentication).</td>
     * </tr>
     * <tr>
     * <td><code>response</code></i></td>
     * <td>Non-empty String</td>
     * <td>The output of the MD5 message digest algorithm applied to the 'key
     * material'.</td>
     * </tr>
     * </table>
     * <p>
     * The 'key material' used to compute the <code>response</code> consists
     * of the String concatenation of:
     * <ol>
     * <li>the user name, </li>
     * <li>the password, and </li>
     * <li>the challenge string, </li>
     * </ol>
     * in that order, turned into a <code>byte[]</code> using
     * {@link String#getBytes()}.
     * <p>
     * That byte array is used to compute the <code>response</code> String as
     * follows:
     * <ol>
     * <li>An MD5 message digest instance is created using
     * <code>java.security.MessageDigest.getInstance("MD5")</code>, then</li>
     * <li>that instance is used to digest the previously constructed
     * <code>byte[]</code> using
     * <code>java.security.MessageDigest.digest(byte[])</code>, which returns
     * another byte[] containing the digested result. Then finally</li>
     * <li>that byte[] digest result is formatted as a precisely 32 character
     * lower-case hexadecimal String by any effective implementation-specific
     * means (watching out to avoid losing possible leading zeros and so on).</li>
     * </ol>
     * The 32 character String resulting from that process is the
     * <code>response</code> argument in the <code>CLIENT</code> packet.
     * <p>
     * An example of possible inputs and the correct resulting response:
     * 
     * <pre>
     *   user=dave
     *   password=foo
     *   challenge=1175186261276/-1155869325
     *   response=3e083042e5f8a94aeccf4a27af8d62f6
     * </pre>
     * 
     * <p>
     * Note that as the case of the <code>response</code> String <i>is</i>
     * considered significant, the validity of the response SHOULD be checked
     * using {@link String#equals(Object)} between the received response and the
     * value locally-computed by the server using the same algorithm.
     * @since 1b (order of key material was wrong)
     */
    static final byte CLIENT = SERVER + 1; // c->s; no; group=string,

    // user=string, response=hexadecimal
    // string

    /**
     * Sent as a final message -- if possible -- when a protocol violation or
     * communications-level problem is detected. <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>client to server or server to single client</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Any</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>1</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>message</code></i></td>
     * <td>Non-empty String</td>
     * <td>Some explanatory text describing the error that occurred, intended
     * as an aid to debugging. </tr>
     * </table>
     * <p>
     * It is a mark of quality to provide useful texts in the
     * <code>message</code>. Debugging network-based distributed software can
     * be extremely difficult, and debugging interoperability problems (bugs
     * that occur between clients and servers of different development teams) is
     * often even harder.
     * <p>
     * A <code>message</code> text like
     * 
     * <pre>
     *                   Null pointer exception
     * </pre>
     * 
     * is <i>phenomenally</i> unhelpful compared to a <code>message</code>
     * like
     * 
     * <pre>
     *                   Required argument 'pid' missing in AUTH, found {id=3, status=&quot;Hi&quot;}
     * </pre>
     * 
     * <p>
     * Note also that sometimes the nature of the problem -- such as an
     * <code>IOException</code> on the TCP channel -- is such that a final
     * {@link #ERROR} packet cannot be delivered. Consequently {@link #ERROR}
     * delivery must be understood to be on a 'best-effort' basis only.
     * Nonetheless it is incumbent upon whichever side detects the error to send
     * a final {@link #ERROR} message if they can.
     * </p>
     * 
     */
    static final byte ERROR = CLIENT + 1; // c->s; s->c1; no; message=string

    /**
     * Sent as a final message when a CGW protocol exchange is in the process of
     * shutting down successfully. <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>client to server or server to single client</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Close</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>0</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * </table>
     * <p>
     */
    static final byte GOODBYE = ERROR + 1; // c->s; s->c1; no; final message

    /**
     * Sent by the server to successfully terminate the initialization phase of
     * a CGW protocol exchange and tell the client its 'player id' number.
     * <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>server to single client</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Initialization</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>2</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>pid</code></i></td>
     * <td>Integer.valueOf(String)</td>
     * <td>The player id number this client will use during the active phase of
     * this protocol exchange. </tr>
     * <tr>
     * <td><code>status</code></i></td>
     * <td>String</td>
     * <td>Any initial status information the server wishes to provide to the
     * client.</tr>
     * 
     * </table>
     * <p>
     * Player ids are non-negative integers that are unique across a single run
     * of a given server -- once used to represent some particular client, the
     * same integer will never be used again unless the server is shut down
     * completely (thereby necessarily breaking all client connections) and
     * restarted.
     * </p>
     * <p>
     * Note that under the CGW protocol, no particular format is required for
     * the 'status' string, except that it is intended to be a human-readable
     * message. Typical sorts of information that might appear in the status
     * could be the number of active players or the (current) tick rate of the
     * server, or similar information, or perhaps some information about any
     * possible delay before this player will become active.
     * </p>
     */
    static final byte AUTH = GOODBYE + 1; // s->c1; no; pid=int,

    // status=string

    /**
     * Broadcast by the server to all active clients announce the arrival of
     * another active player. Also sent directly to a newly-active player to
     * inform it of the other pre-existing active players.<table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>server broadcast to active clients</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>3</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>client</code></i></td>
     * <td>Non-empty String</td>
     * <td>The string identifying the type of client program the newly-joined
     * player is running. This value is equal to the <code>group</code>
     * argument provided in the {@link #CLIENT} packet received during the
     * initialization phase.</tr>
     * <tr>
     * <td><code>user</code></i></td>
     * <td>Non-empty String</td>
     * <td>The authorized user name of the newly-joined player. This value is
     * equal to the <code>user</code> argument provided in the {@link #CLIENT}
     * packet received during the initialization phase.</tr>
     * <tr>
     * <td><code>pid</code></i></td>
     * <td>Integer.valueOf(String)</td>
     * <td>The player id number of the newly-arrived client. </tr>
     * <tr> </table>
     * <p>
     * Note that the newly-arrived client <i>does</i> receive the
     * <code>JOIN</code> packet announcing their own arrival, and that
     * <code>JOIN</code> packet <b>MUST</b> be the <i>first</i> packet the
     * client receives after they receive the {@link #AUTH} packet, or else the
     * server has made a CGW protocol violation.
     * </p>
     * <p>
     * As discussed in the 'active phase' section in the class Javadoc above, as
     * part of a new player's 'startup package', additional <code>JOIN</code>
     * packets are delivered just to the newly-arrived client, one for each
     * active player preexisting at the time the newly-arrived client enters the
     * active phase. It is <i>not</i> a protocol violation for a server to send
     * redundant <code>JOIN</code> packets reiterating still-valid unchanged
     * previously-delivered information, although they are encouraged not to;
     * clients MUST ignore or otherwise suitably handle such duplicates without
     * becoming confused about the total number of active players -- which is
     * defined as the number of unique player ids received in <code>JOIN</code>
     * packets for which there has been no subsequent {@link #LEAVE} packet.
     * </p>
     */
    static final byte JOIN = AUTH + 1; // s->c*; no; client=string,

    // user=string,

    // pid=int

    /**
     * Sent in both directions between clients and servers to implement 'text
     * chatting'. <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>client to server to 'speak'; server broadcast to <i>selected</i>
     * active clients to 'hear'</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>3</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>from</code></i></td>
     * <td>Integer.valueOf(String)</td>
     * <td>The player id who initiated this chat. It is a protocol violation
     * for a client to send a <code>CHAT</code> packet that does not include
     * just that client's own player id as the <code>from</code> argument.</tr>
     * <tr>
     * <td><code>to</code></i></td>
     * <td>possibly empty whitespace-separated int list</td>
     * <td>A list of player ids to send this chat to. </td>
     * <tr>
     * <td><code>message</code></i></td>
     * <td>String</td>
     * <td>The message text to be sent from the 'from' player to the 'to'
     * players.
     * <tr> </table>
     * <p>
     * The handling of the 'to' argument requires additional explanation:
     * <ul>
     * <li>The 'to' argument may be an empty String, which implies a request to
     * broadcast the message to all active clients.</li>
     * <li>Otherwise it is a list of player ids represented as decimal integers
     * separated by single space characters, which implies a request to forward
     * to just those player ids.</li>
     * <li>It is a protocol violation to specify anything but a possibly empty
     * list of single-space-separated non-negative decimal integers as the 'to'
     * argument.</li>
     * <li>It is <i>not</i> a protocol violation if one or more of the
     * specified integers fails to name a currently active player id; should
     * that occur that particular playerid specification is simply skipped as a
     * delivery location for the chat packet, and that invalid playerid
     * specification <i>does</i> remain in the 'to' argument that is delivered
     * to any validly-named player ids. </li>
     * <li>It is <i>not</i> a protocol violation to chat only to oneself
     * (e.g., if the 'from' and 'to' arguments are identical.</li>
     * <li>As discussed in the 'active phase' section of the class Javadoc
     * above, servers MAY impose additional restrictions on interclient
     * awareness and communication, and if they do, some legal playerids may
     * also be skipped due to being in different 'active sets'. </li>
     * </ul>
     */
    static final byte CHAT = JOIN + 1; // c->s, s->c*; no; message=string,

    // from=int to=int list

    /**
     * Occurs when a player clicks on a 'soft button' defined by a previously
     * received {@link #BUTTON} packet. <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>client to server only</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>2</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>name</code></i></td>
     * <td>Non-empty String</td>
     * <td>The name of the soft button the player has clicked.</tr>
     * <td><code>bumber</code></i></td>
     * <td>Integer.valueOf(String)</td>
     * <td>The 'button number' that player used to clicked on this button, as
     * reported by <code>MouseEvent#getButton()</code>.</tr>
     * </table>
     * <p>
     * The 'name' argument to the <code>Click</code> Packet is identical to
     * the 'name' argument of the {@link #BUTTON} packet that defined the soft
     * button the player has clicked.
     * <p>
     * Because of possible race conditions between clients and servers, it is
     * possible that a conforming CGW client <i>might</i> issue a
     * <code>Click</code> Packet naming a soft button that is no longer legal
     * on the server side due to an in-flight {@link #RESET} packet the client
     * has not yet received.
     * <p>
     * For that reason, servers MUST NOT treat the arrival of a
     * <code>CLICK</code> naming a no-longer-defined {@link #BUTTON} as a
     * protocol violation. Such <code>CLICK</code> packets SHOULD be silently
     * ignored. Servers MAY treat <code>CLICK</code> packets naming a
     * <i>never-defined</i> <code>BUTTON</code> as a protocol violation, but
     * they are not required to.
     * <p>
     * Clients MUST NOT issue a <code>CLICK</code> packet naming a
     * <code>BUTTON</code> that was never received from the server, and SHOULD
     * NOT issue a <code>CLICK</code> packet naming a <code>BUTTON</code>
     * that has been eliminated by a received {@link #RESET} packet and not
     * (yet) subsequently redefined.
     * </p>
     */
    static final byte CLICK = CHAT + 1; // c->s; no; name=string

    /**
     * Sent by a player to set the 'running speed' of their gang. <table
     * border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>client to server only</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>1</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>rate</code></i></td>
     * <td>Integer.valueOf(String)</td>
     * <td>The non-negative ticks-per-step at which to run this player's gang.
     * "0" means don't step the gang at all.</td>
     * </tr>
     * </table>
     * <p>
     * A CGW server runs at some number of <i>ticks per second</i>, and various
     * events may occur on each and every tick, but not every gang necessarily
     * takes an active 'step' on every tick.
     * <p>
     * 'Stepping a gang' gives each gang Member one chance to move, in chain
     * order starting from the front of the chain. The <code>rate</code>
     * argument to the <code>RUN</code> Packet specifies how frequently to
     * step the gang, in terms of ticks per step. A <code>rate</code> value of
     * "0" is a special case meaning do not step the gang at all (until further
     * notice), a value of "1" means step the gang on every tick (this is the
     * maximum stepping speed), "2" means every other tick, and so on.
     * <p>
     * (See also {@link #STEP} for another way to affect the gang's
     * ticks-per-step.)
     * <p>
     * Stepping a gang requires power, and power is limited, so for strategic
     * reasons techs often choose to step their gangs relatively slowly except
     * when needed. Gangs accrue one unit of 'power' at some server-defined
     * <code>ticks-per-powerup</code>, and they step (and spend one unit of
     * their accumulated power) when their number of ticks since their last step
     * exceeds their prevailing <code>ticks-per-step</code>.
     * <p>
     * If a gang's prevailing <code>ticks-per-step</code> is larger than the
     * server's <code>ticks-per-powerup</code>, that gang will more or less
     * gradually gain power over time, and vice versa.
     * <p>
     * Note that servers MAY change their tick rate (which is measured in terms
     * of ticks-per-wall-clock-second) over time (e.g., in response to varying
     * processing loads, particular game activities, client latencies, etc) but
     * in general the server tick rate SHOULD NOT be varied capriciously.
     * <p>
     * Implementors should note that just because a gang isn't stepping on a
     * given tick, that doesn't mean nothing can happen to the gang. On the
     * contrary, Members of such gangs can be damaged due to external causes,
     * which can cause their state to change or for them to be destroyed
     * entirely. So it is common for a server to send {@link #UPDATE} packets
     * concerning gangs that did not choose to move on that tick.
     * </p>
     */
    static final byte RUN = CLICK + 1; // c->s; no; rate=int 0 means pause

    /**
     * Sent by a player to request a single step of their gang followed by an
     * indefinite pause in stepping. <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>client to server only</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>0</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * </table>
     * <p>
     * A <code>STEP</code> requests that the player's gang take one step on
     * the next tick to occur after the arrival of the <code>STEP</code>
     * packet, but that in addition the gang's<code>ticks-per-step</code>
     * rate be set to 0, so that no further automatic stepping will occur.
     * <p>
     * See {@link #RUN} for the main documentation concern gang stepping and
     * <code>ticks-per-step</code>.
     * <p>
     * Note that <code>STEP</code> packets only <i>request</i> a step on the
     * next tick; they do not cause an <i>immediate</i> step, so a client
     * cannot exceed the maximum step-every-tick frequency by issuing multiple
     * rapid <code>STEP</code> packets -- multiple <code>STEP</code>s
     * received before the same tick have the same effect as a single
     * <code>STEP</code>.
     */
    static final byte STEP = RUN + 1; // c->s; no; do one step now then set

    // rate to 0

    /**
     * May be sent by client to <i>request</i> a game reset, and is broadcast
     * from server to active clients when a game reset actually occurs.
     * <p>
     * Clients may send <code>RESET</code> to indicate a desire to start over,
     * whatever that means in the context of the particular server. Whether any
     * such requests will be granted or not is determined by purely
     * <i>implementation-specific</i> server-side criteria -- client reset
     * requests may be always ignored, or always granted, or granted at certain
     * times or on the basis of majority requests, etc. Server-side implementors
     * SHOULD use their sense of balance and design in the context of their
     * particular games to determine how to implement resetting with the
     * greatest playability.<table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>client to server (request); server to client (event notification)</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>2</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * <tr>
     * <td><code>width</code></i></td>
     * <td>Integer.valueOf(String)</td>
     * <td>The positive integer number of columns in the yard.</td>
     * </tr>
     * <tr>
     * <td><code>height</code></i></td>
     * <td>Integer.valueOf(String)</td>
     * <td>The positive integer number of rows in the yard.</td>
     * </tr>
     * </table>
     * <p>
     * The <code>RESET</code> packet MAY be sent from client to server to
     * request a game start or restart.  In such cases the values of the
     * required 'width' and 'height' arguments should be ignored.  The results 
     * of <code>RESET</code> packets sent from client to server is
     * implementation-specific.
     * <p>
     * By contrast, the effects of a <code>RESET</code> sent by the
     * server are required by the CGW protocol. Specifically, upon the receipt
     * receipt of a <code>RESET</code>, a client must do the following:
     * <ol>
     * <li>It MUST remove from the user interface any 'soft buttons' it
     * previously was displaying as the result of prior {@link #BUTTON} packets,
     * and</li>
     * <li>it MUST discard any cached Gang definitions it may have been
     * maintaining, and</li>
     * <li>it MUST configure itself appropriately to be ready to handle and
     * display a yard in which the legal x coordinates run from 0 to 'width'-1, and the 
     * legal y coordinates run from 0 to 'height'-1, for the 'width' and 'height'
     * arguments supplied in the <code>RESET</code> packet, but</li>
     * <li>it MUST NOT discard its records of active players, since that
     * information will not necessarily be refreshed after a <code>RESET</code>.
     * </ol>
     */
    static final byte RESET = STEP + 1; // c->s; s->c*; no; req/do reset of

    // gangs

    // and buttons

    /**
     * Sent by server to define a 'soft button'. A server can request display of
     * arbitrary clickable buttons in the client interface by sending
     * <code>BUTTON</code> packets.
     * <p>
     * Clients MUST be able to display no less than 10 'soft buttons' containing
     * plain text labels of no less than 20 characters each, but clients SHOULD
     * be able to handle larger and more numerous buttons and MAY choose to
     * provide mechanisms supporting essentially unlimited accessible 'button
     * space'. <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>server to client</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>3</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>name</code></i></td>
     * <td>Non-empty String</td>
     * <td>The unique-across-all-<code>BUTTON</code>s identifier to be
     * associated with this button.</td>
     * </tr>
     * <tr>
     * <td><code>label</code></i></td>
     * <td>String</td>
     * <td>The text label for the client to display on the button.</td>
     * </tr>
     * <tr>
     * <td><code>tip</code></i></td>
     * <td>String</td>
     * <td>The text 'tool tip' for the client to display when the mouse hovers
     * over this button.</td>
     * </tr>
     * </table>
     * <p>
     * The <code>name</code> argument of is what is returned to the server as
     * the <code>name</code> argument to a {@link #CLICK} packet, and it
     * serves no other inherent purpose; it is not intended for display to the
     * human user.
     * <p>
     * The server may respond in any way it wishes to the <code>CLICK</code>ing
     * of a soft button; it may distinguish between different buttons, or not,
     * etc.
     */
    static final byte BUTTON = RESET + 1; // s->c*; no; name=string;

    // label=string; tip=string

    /**
     * Sent by server to define a Gang, sent by client to request or guide the
     * deployment of the player's gang. <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>client to server (deployment request); server to client (gang
     * definition)</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>Yes</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>1</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>color</code></i></td>
     * <td>Empty String or Integer.valueOf(String)</td>
     * <td>If present, an RGB color <i>suggestion</i> of a possible
     * color to use in rendering this gang.</td>
     * </tr>
     * </table>
     * <p>
     * This is one of the two CGW packet types (the other being {@link #UPDATE}
     * that include CGC-compressed data in the {@linkplain Packet#opcodes} array
     * in addition to the packet type that always resides in
     * <code>opcodes[0]</code>.
     * <p>
     * See the CGC document for details on the format and interpretation of the
     * <code>opcodes</code> data.
     * <p>
     * The color argument value is either an empty string or a integer value acceptable
     * to Integer.valueOf(String).  If it is an empty string, then no suggested color
     * for this gang is being provided.  Otherwise, the resulting integer value is a 
     * <i>suggested</i> color to use (or 'involve') in the rendering of this gang, and
     * the integer value is of a form suitable to pass as the 'rgb' argument in a
     * <code>java.awt.Color(int rgb)</code> constructor invocation.
     * <p>
     * Note that any such provided arguments are merely <i>advisory</i> to 
     * rendering clients.  Clients may have their own color palettes, and may have
     * methods of distinguishing gangs that do not depend on color at all; clients
     * are under no obligation to use the information supplied in a non-empty 'color'
     * argument in a <code>GANG</code> Packet.
     *   
     * <p>However, if it is reasonably convenient within their HCI design, clients are 
     * <i>encouraged</i> to employ such a supplied color in some capacity identified 
     * with the gang, to provide a degree of commonality in rendering and allow
     * free text CHAT messages to refer to the 'red' gang or whatever with some hope
     * of that being a consistent reference.
     * 
     * @since 1a (color argument)
     */
    static final byte GANG = BUTTON + 1; // c->s; s->c*; yes; req gang disp

    // on -1,

    // define gang

    /**
     * Sent by server to update a Gang of whichthe client is already aware.
     * <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>server to client</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>Yes</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>0</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * </table>
     * <p>
     * This is the other of the two CGW packet types (the first being
     * {@link #GANG} that include CGC-compressed data in the
     * {@linkplain Packet#opcodes} array in addition to the packet type that
     * always resides in <code>opcodes[0]</code>.
     * <p>
     * See the CGC document for details on the format and interpretation of the
     * <code>opcodes</code> data.
     */
    static final byte UPDATE = GANG + 1; // s->c; yes;

    /**
     * Sent by client to issue a 'tech order' to a gang leader, instructing it
     * to try to move in a certain direction.
     * <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>client to server</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>2</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>who</code></i></td>
     * <td>Integer.valueOf(String)</td>
     * <td>The member id of the gang leader to which this tech order is
     * addressed.</td>
     * </tr>
     * <tr>
     * <td><code>dir</code></i></td>
     * <td>Integer.valueOf(String)</td>
     * <td>A 'direction code' in the range of 1..9.</td>
     * </tr>
     * </table>
     * <p>
     * Each gang member can be referred to by a 'member id' that is implicit in
     * the CGC data defining the gang; the <code>who</code> argument specifies
     * such a member id.  The member id consists of a gangid in the high 16 
     * bits and a member number in the low 16 bits, with member numbers counting
     * forward from 0 at the head of the chain gang.  (In the standard semantics
     * the only MOVE-commandable member <i>is</i> at the head of the gang, so
     * the low 16 bits of the <code>who</code> argument to a <code>MOVE</code> 
     * will always be 0 in the standard semantics.) 
     * <p>
     * The <code>dir</code> argument contains a number from 1 to 9 inclusive,
     * that specifies one of 9 'directions' following the layout of a standard
     * numeric keypad, as shown in this diagram, which also defines the
     * corresponding 2D (X,Y) offset values for each of the directions
     * (remembering that Y values <b>MUST</b> increase <i>downward</i> in CGW
     * client displays):
     * 
     * <pre>
     *                  7         8         9
     *                 NW       North       NE
     *              (-1,-1)     (0,-1)     (1,-1)     
     *                     
     *                                 
     *           West   4         5         6   East
     *              (-1,0)      (0,0)      (1,0)           
     *                         
     *                                   
     *                  1         2         3            
     *                 SW       South       SE
     *              (-1,1)      (0,1)      (1,1)
     *      
     * </pre>
     * 
     * <p>
     * If a <code>who</code> argument refers to a member id that never
     * existed, no longer exists, or belongs to gang not controlled by this
     * player, that is <i>not</i> a protocol violation; the <code>MOVE</code>
     * is simply ignored.
     * <p>
     * If a <code>dir</code> argument is outside the range 1..9, that is a
     * client-side protocol violation.
     * @since 1a (updates to member id)
     */
    static final byte MOVE = UPDATE + 1; // c->s; s->c1; no; who=int (leader)

    // dir=int 1..9

    /**
     * Sent by client to issue a 'tech order' to a gang follower, instructing it
     * to try to follow a specific other member or move to a certain location.
     * <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>client to server</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>2</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>who</code></i></td>
     * <td>Integer.valueOf(String)</td>
     * <td>The member id of the gang follower to which this tech order is
     * addressed.</td>
     * </tr>
     * <tr>
     * <td><code>goal</code></i></td>
     * <td>one int or two ints separated by a single space</td>
     * <td>If one int, a member id to follow; if two ints, a coordinate to move
     * to.</td>
     * </tr>
     * </table>
     * <p>
     * A <code>TELL</code> packet instructs a follower member to abandon its
     * normal 'follow the upchain normals' programming, and instead close on a
     * specific target, which is either a member id or a grid coordinate in the
     * yard. If following a <code>TELL</code> causes the follower member to
     * move too far away from its upchain associates, however, that will trigger
     * the Initiative Suppression feedback clamp circuits which will detonate
     * the member's explosive load.
     * <p>
     * If the <code>who</code> does not name a currently existing member of
     * this tech's gang, the <code>TELL</code> order is simply ignored. If the
     * <code>goal</code> is a single int that does not name a currently
     * existing member of this tech's gang, or is two space-separated ints that
     * does not name a valid coordinate in the yard, the <code>TELL</code>
     * order is simply ignored.
     * <p>
     * A follow member successfully ordered by a <code>TELL</code> continues
     * to approach the specified goal as long as it is able to do so. If it
     * reaches its specified grid coordinate goal it will stay there. As long as
     * its specified member goal still exists, it will attempt to move to that
     * member's current location. If the specified member goal ceases to exist,
     * however, the follow member will abandon its <code>TELL</code> order and
     * return to its normal follower programming.
     * <p>
     * As a special case, if a member is ordered by a <code>TELL</code> to approach
     * its immediate upchain member, <i>and</i> it successfully becomes adjacent to it, then 
     * at that point also the 'told' member will abandon its <code>TELL</code> order and
     * return to its normal follower programming.
     * @since 1a (special case)
     */

    static final byte TELL = MOVE + 1; // c->s; s->c1; no; who=int target=int

    // or

    // coord

    /**
     * Sent by client to request deactivation and leaving the server cleanly.
     * <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>client to server</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>0</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * </table>
     * <p>
     * A <code>QUIT</code> packet requests to initiate a transition from the
     * active phase to the close phase, as discussed in the 'active phase'
     * section of the class JavaDoc, above.
     */
    static final byte QUIT = TELL + 1; // c->s; no; req death

    /**
     * Sent by server to notify a client that it has left the game.
     * <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>server to client</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>0</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * </table>
     * <p>
     * A <code>DIED</code> packet notifies the client that it has
     * left the active phase and is now in the close phase, as discussed 
     * in the class JavaDoc, above.
     */
    static final byte DIED = QUIT + 1; // s->c1; no; pid=int cause=string

    /**
     * Broadcast by the server to all active clients announce the departure of
     * a previously active player. <table border=1>
     * <tr>
     * <td><i>Packet direction</i></td>
     * <td>server broadcast to active clients</td>
     * </tr>
     * <tr>
     * <td><i>Phase(s)</i></td>
     * <td>Active</td>
     * </tr>
     * <tr>
     * <td><i>CGC data included</i></td>
     * <td>No</td>
     * </tr>
     * <tr>
     * <td><i>Required arguments</i></td>
     * <td>2</td>
     * </tr>
     * </table>
     * <p>
     * Required arguments:<table border=1>
     * <tr>
     * <td><i>Key</i></td>
     * <td><i>Value format</i></td>
     * <td><i>Description</i></td>
     * </tr>
     * <tr>
     * <td><code>cause</code></i></td>
     * <td>String</td>
     * <td>A description of the reason this <code>LEAVE</code>
     * Packet was generated (e.g., error, player quit, gang
     * eliminated, etc).</tr>
     * <tr>
     * <td><code>pid</code></i></td>
     * <td>Integer.valueOf(String)</td>
     * <td>The player id number of the just-departed client. </tr>
     * <tr> </table>
     * <p>
     * Note that the just-departed client <i>does not</i> receive the
     * <code>LEAVE</code> packet announcing their own departure, or else the
     * server has made a CGW protocol violation.
     * </p>
     */
    static final byte LEAVE = DIED + 1; // s->c*; no; pid=int cause=string

    /**
     * The number of defined CGW packet types.
     */
    static final byte MAX_CMD = LEAVE + 1;
}
